﻿Imports System.Runtime.InteropServices
Imports System.Runtime.CompilerServices
Imports System.Security
Imports System.IO
Imports System.Text
Imports System.Collections.ObjectModel

Module Utilities
    <Extension()> Public Function ToSecureString(ByVal str As String) As SecureString
        If str Is Nothing Then str = String.Empty
        Dim S As New SecureString()
        For i = 0 To str.Length - 1
            S.AppendChar(str(i))
        Next i
        Return S
    End Function

    <Extension()> Public Function DeSecure(ByVal SecureStr As SecureString) As String
        If SecureStr Is Nothing Then Return String.Empty
        Dim BSTR As IntPtr = Marshal.SecureStringToBSTR(SecureStr)
        Dim Result As String = Marshal.PtrToStringBSTR(BSTR)
        Marshal.ZeroFreeBSTR(BSTR)
        Return Result
    End Function

    <Extension()>
    Function ClassToString(Of T As Class)(ByVal obj As T) As String
        Dim r As String
        Try
            Using stream = New MemoryStream(200)
                Dim S = New Xml.Serialization.XmlSerializer(GetType(T))
                S.Serialize(stream, obj)
                Using reader = New StreamReader(stream, Encoding.UTF8)
                    stream.Seek(0, SeekOrigin.Begin)
                    r = reader.ReadToEnd
                End Using
                stream.Close()
            End Using
            Return r
        Catch ex As Exception
            Return String.Empty
        End Try
    End Function

    Private ReadOnly CachedClass As New Dictionary(Of String, Object)()

    <Extension()>
    Function ToClass(Of T As Class)(ByVal str As String) As T
        If CachedClass.ContainsKey(str) Then
            Return CachedClass(str)
        End If
        Dim r As T = Nothing
        Try
            Using stream = New MemoryStream(Encoding.UTF8.GetBytes(str), False)
                Dim S = New Xml.Serialization.XmlSerializer(GetType(T))
                r = S.Deserialize(stream)
                stream.Close()
            End Using
            CachedClass.Add(str, r)
        Catch ex As Exception

        End Try
        Return r
    End Function

    Function EmptyArray(Of T)() As T()
        Dim L As New List(Of T)
        Return L.ToArray
    End Function

    Dim d As New Microsoft.WindowsAPICodePack.Dialogs.CommonOpenFileDialog("添加搜索目录")

    Sub New()
        d.IsFolderPicker = True
        d.Multiselect = False
        d.NavigateToShortcut = True
        d.Title = "选择插件目录"
        d.EnsurePathExists = True
    End Sub

    Sub AddPath(ByRef paths As String())
        If d.ShowDialog = Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialogResult.Ok Then
            paths = If(paths.Contains(d.FileName), paths, paths.Concat({d.FileName}).ToArray)
        End If
    End Sub

    Sub AddPath(ByVal paths As List(Of String))
        If d.ShowDialog = Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialogResult.Ok Then
            Dim f = d.FileName
            If Not paths.Contains(f) Then
                paths.Add(f)
            End If
        End If
    End Sub

    Sub AddPath(ByVal paths As ObservableCollection(Of String))
        If d.ShowDialog = Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialogResult.Ok Then
            Dim f = d.FileName
            If Not paths.Contains(f) Then
                paths.Add(f)
            End If
        End If
    End Sub

    Public Class EqualityMaker(Of T)
        Inherits EqualityComparer(Of T)

        Private EqualFunction As Func(Of T, T, Boolean)
        Private GetHashCodeFunction As Func(Of T, Integer)

        Public Sub New()
            EqualFunction = AddressOf EqualityComparer(Of T).Default.Equals
            GetHashCodeFunction = AddressOf EqualityComparer(Of T).Default.GetHashCode
        End Sub

        Public Sub New(equalityFunc As Func(Of T, T, Boolean))
            GetHashCodeFunction = AddressOf EqualityComparer(Of T).Default.GetHashCode
            EqualFunction = equalityFunc
        End Sub

        Public Sub New(equalityFunc As Func(Of T, T, Boolean), hasherFunc As Func(Of T, Integer))
            EqualFunction = equalityFunc
            GetHashCodeFunction = hasherFunc
        End Sub

        Public Overloads Overrides Function Equals(x As T, y As T) As Boolean
            Return EqualFunction(x, y)
        End Function

        Public Overloads Overrides Function GetHashCode(obj As T) As Integer
            Return GetHashCodeFunction(obj)
        End Function
    End Class


    <DllImport("user32.dll", CharSet:=CharSet.Auto, EntryPoint:="RegisterHotKey")>
    Function RegisterHotKey(hwnd As IntPtr, id As Integer, control As UInteger, key As Key) As Boolean

    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, EntryPoint:="UnregisterHotKey")>
    Function UnregisterHotKey(hwnd As IntPtr, id As Integer) As Boolean

    End Function
End Module
